//#include <iostream>
//using namespace std;
//const int N = 405;
//
//int dis[N][N];
//int n, m;
//int dir[8][2] = { //偏移量
//	{2,1},{-2,1},{2,-1},{-2,-1},
//	{1,2},{1,-2}, {-1,2},{-1,-2}
//};
//void dfs(int step, int x, int y)
//{
//	if (dis[x][y] != -1 && dis[x][y] <= step) return;
//	dis[x][y] = step;
//	for (int k = 0; k < 8; k++) {
//		int dx = x + dir[k][0], dy = y + dir[k][1]; 
		//if (dx<1 || dx>n) continue;
		//if (dy<1 || dy>m) continue;
//		dfs(step + 1, dx, dy);
//	}
//}
//
//
//int main()
//{
//
//	int a, b;
//	cin >> n >> m >> a >> b;
//	for (int i = 1; i <= n; i++) {
//		for (int j = 1; j <= m; j++) {
//			dis[i][j] = -1; //赋初值
//		}
//	}
//	dfs(0, a, b); //到达当前点所花步数，(a,b)表示当前所在位置
//
//	for (int i = 1; i <= n; i++) {
//		for (int j = 1; j <= m; j++) {
//			cout << dis[i][j] << " ";
//		}
//		cout << "\n";
//	}
//
//	return 0;
//}



//上面超时，BDS
#include <iostream>
#include <queue>
using namespace std;
const int N = 405;
int dir[8][2] = { //偏移量
	{2,1},{-2,1},{2,-1},{-2,-1},
	{1,2},{1,-2}, {-1,2},{-1,-2}
};

int dis[N][N];
int n, m;

struct Node { //广搜队列
	Node(int x, int y, int s) :x(x), y(y), s(s) {}
	int x, y, s;
};


void bfs(int a, int b){
	queue<Node> q;
	q.push(Node(a, b, 0));
	dis[a][b] = 0;

	//从当前节点扩展到其他点
	while (!q.empty()) {
		Node now = q.front();
		q.pop();
		for (int k = 0; k < 8; k++) {
			int dx = now.x + dir[k][0], dy = now.y + dir[k][1];
			if (dx < 1 || dx > n) continue;
			if (dy < 1 || dy > m) continue;
			if (dis[dx][dy] != -1)continue;
			q.push(Node(dx, dy, now.s + 1));
			dis[dx][dy] = now.s + 1;
		}
	}

}


int main()
{

	int a, b;
	cin >> n >> m >> a >> b;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			dis[i][j] = -1; //赋初值
		}
	}
	bfs(a, b); //到达当前点所花步数，(a,b)表示当前所在位置

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cout << dis[i][j] << " ";
		}
		cout << "\n";
	}

	return 0;
}
